package puzzle.common.solver.topology;

import java.util.ArrayList;
import java.util.List;

import puzzle.common.point.Pnt;
import puzzle.common.solver.Track;
import puzzle.common.solver.TrackTopology;
import tomoto.util.Pair;

public class TrackAnalyzer {
	public TrackTopology analyze(TrackAnalyzable g) {
		int trackNumber = 0;
		Pnt p;
		List<Track> tracks = new ArrayList<Track>();
		while ((p = g.findNextNode()) != null) {
			trackNumber++;
			Track t0 = findEnd(g, p, trackNumber);
			Track t1 = findEnd(g, p, trackNumber);
			Track t = connectTracks(t0, t1);
			if (t != null) {
				tracks.add(t);
			}
		}
		return new TrackTopology(tracks);
	}

	private Track findEnd(TrackAnalyzable g, Pnt p0, int trackNumber) {
		int leg = 0;
		Pnt p1 = p0;
		Pnt p;
		while ((p = g.navigateUnvisitedEdgeFrom(p1, trackNumber)) != null) {
			leg++;
			p1 = p;
		}
		return (leg > 0) ? new Track(new Pair<Pnt>(p0, p1), leg) : null;
	}

	private Track connectTracks(Track t0, Track t1) {
		if (t0 == null) return t1;
		if (t1 == null) return t0;
		assert t0.getEnds().car.equals(t1.getEnds().car);
		return new Track(new Pair<Pnt>(t0.getEnds().cdr, t1.getEnds().cdr), t0.getLeg()
				+ t1.getLeg());
	}
}
